package com.molichuxing.gateway.bff.car.services.impl;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.UploadFileRequestDto;
import com.molichuxing.framework.dto.UploadFileResponseDto;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.result.ResponseCodeEnum;
import com.molichuxing.framework.result.ResponseResult;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.framework.utils.EmailUtil;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.framework.utils.PoiExcelUtils;
import com.molichuxing.framework.utils.UploadUtil;
import com.molichuxing.gateway.bff.basic.services.FileStorageBffService;
import com.molichuxing.gateway.bff.car.convertor.Convert;
import com.molichuxing.gateway.bff.car.entity.request.modify.CarDetailModifyVo;
import com.molichuxing.gateway.bff.car.entity.response.CarDetailVo;
import com.molichuxing.gateway.bff.car.entity.response.CarVo;
import com.molichuxing.gateway.bff.car.entity.response.IovTrajectoryVo;
import com.molichuxing.gateway.bff.car.services.CarBffService;
import com.molichuxing.gateway.property.PowerTypeEnum;
import com.molichuxing.gateway.property.StockStatusEnum;
import com.molichuxing.gateway.utils.PoiExcelUtil;
import com.molichuxing.gateway.utils.entity.UserEntity;
import com.molichuxing.services.business.dto.request.create.VehicleCreateBizDto;
import com.molichuxing.services.business.dto.response.CarBizDto;
import com.molichuxing.services.business.dto.response.DealerStoreInfoBizDto;
import com.molichuxing.services.business.dto.response.StockCarBizDto;
import com.molichuxing.services.business.dto.response.VehicleNameBizDto;
import com.molichuxing.services.business.service.CarBizService;
import com.molichuxing.services.business.service.StockCarBizService;
import com.molichuxing.services.business.service.StoreBizService;
import com.molichuxing.services.business.service.VehicleBizService;
import com.molichuxing.services.infrastructure.dto.request.create.StockCarCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.CarDetailModifyDto;
import com.molichuxing.services.infrastructure.dto.response.CarDetailDto;
import com.molichuxing.services.infrastructure.dto.response.CarDto;
import com.molichuxing.services.infrastructure.dto.response.IovMileageDto;
import com.molichuxing.services.infrastructure.dto.response.IovTrajectoryDto;
import com.molichuxing.services.infrastructure.dto.response.OwnershipDto;
import com.molichuxing.services.infrastructure.dto.response.StockCarDto;
import com.molichuxing.services.infrastructure.dto.response.StockStoreDto;
import com.molichuxing.services.infrastructure.dto.response.VehicleColorDto;
import com.molichuxing.services.infrastructure.dto.response.VehicleDto;
import com.molichuxing.services.infrastructure.dto.response.VehiclePictureDto;
import com.molichuxing.services.infrastructure.service.CarDetailService;
import com.molichuxing.services.infrastructure.service.CarService;
import com.molichuxing.services.infrastructure.service.EnterpriseCarService;
import com.molichuxing.services.infrastructure.service.IovCarService;
import com.molichuxing.services.infrastructure.service.OrderDealerDeliveryService;
import com.molichuxing.services.infrastructure.service.OwnershipService;
import com.molichuxing.services.infrastructure.service.StockCarService;
import com.molichuxing.services.infrastructure.service.StockStoreService;
import com.molichuxing.services.infrastructure.service.VehicleColorService;
import com.molichuxing.services.infrastructure.service.VehiclePictureService;
import com.molichuxing.services.infrastructure.service.VehicleService;
import com.molichuxing.services.property.CarsBusinessTypeEnum;
import com.molichuxing.services.property.CarsOperateStatusEnum;
import com.molichuxing.services.property.CarsTypeEnum;
import com.molichuxing.services.property.StockCarStatusEnum;
import com.molichuxing.services.property.StockCarStockTypeEnum;
import com.molichuxing.services.property.StockCarTypeEnum;

/**
 * 车辆bff
 * @author xuelin yi
 */
@Service("carBffService")
public class CarBffServiceImpl implements CarBffService {

    private static final Logger logger = LoggerFactory.getLogger(CarBffServiceImpl.class);

    @Resource
    private CarBizService carBizService;

    @Resource
    private CarService carService;

    @Resource
    private CarDetailService carDetailService;

    @Resource
    private VehicleColorService vehicleColorService;

    @Resource
    private VehicleBizService vehicleBizService;

    @Resource
    private VehicleService vehicleService;

    @Resource
    private OwnershipService ownershipService;

    @Resource
    private StockStoreService stockStoreService;

    @Resource
    private StockCarBizService stockCarBizService;

    @Resource
    private FileStorageBffService fileStorageBffService;

    @Resource
    private StoreBizService storeBizService;

    @Resource
    private IovCarService iovCarService;

    @Resource
    private StockCarService stockCarService;

    @Resource
    private VehiclePictureService vehiclePictureService;
    
    @Resource
    private EnterpriseCarService enterpriseCarService;
    
    @Resource
    private OrderDealerDeliveryService orderDealerDeliveryService;

    @Value("${email_account}")
    private String emailAccount;
    @Value("${email_password}")
    private String emailPassword;

    @Override
    public Paged<CarVo> getCarList(Map<String, Object> selectParams, Integer pageNum, Integer pageSize) {
        Integer vehicleLockStatus = ObjectCastUtil.castInteger(selectParams.get("vehicleLockStatus"));
        Integer stockType = ObjectCastUtil.castInteger(selectParams.get("stockType"));
        Integer stockId = ObjectCastUtil.castInteger(selectParams.get("stockId"));
		long startTime = System.currentTimeMillis();
        if ((null != stockType) && (StockCarStockTypeEnum.STORE.getValue() == stockType) && null != stockId) {
            StockStoreDto stockStoreDto = stockStoreService.getStockStoreByStoreId(stockId);
            if (stockStoreDto == null) {
                selectParams.put("stockId", 0);
            } else {
                selectParams.put("stockId", stockStoreDto.getStockId());
            }
        }
        if (vehicleLockStatus == null) {
            Paged<CarDto> carDtoList = carService.getCarPage(selectParams, pageNum, pageSize);
            Paged<CarVo> page = Convert.toCarVoPage(carDtoList, getVehicleName(carDtoList.getList()), getVehicleColor(carDtoList.getList()));
            logger.info("查询库时间：{}",( System.currentTimeMillis()-startTime)/1000+"s");
            getVehicleStock(page.getList());
            return page;
        } else {
            //车联网开启动力
            List<String> strings = doHandler();
            logger.info("iov响应时间：{}",( System.currentTimeMillis()-startTime)/1000+"s");
            selectParams.put("vehicleLockStatus",vehicleLockStatus);
            selectParams.put("vinList",strings);
            Paged<CarDto> carDtoList = carService.getCarPage(selectParams, pageNum, pageSize);
            Paged<CarVo> page = Convert.toCarVoPage(carDtoList, getVehicleName(carDtoList.getList()), getVehicleColor(carDtoList.getList()));
            logger.info("查询库时间：{}",( System.currentTimeMillis()-startTime)/1000+"s");
            getVehicleStock(page.getList());
            if(page!=null&&!CollectionUtils.isEmpty(page.getList())){
                for (CarVo carVo : page.getList()) {
                    if (strings.contains(carVo.getVin())){
                        carVo.setVehicleLockStatus(1);
                    }else{
                        carVo.setVehicleLockStatus(2);
                    }
                }
            }
            return page;
        }
    }
    private List<String> doHandler()  {
        /**
         * 锁车状态
         */
        List<String> list = new ArrayList<>();
        Map<String, Object> maps = iovCarService.getCarControlStatus();
        if (!CollectionUtils.isEmpty(maps)) {
            for (Map.Entry<String, Object> entry : maps.entrySet()) {
                //1关闭
                int res = entry.getValue() == null ? 3 : Integer.parseInt(entry.getValue().toString());
                if (res != 1&&res != 3) {
                    list.add(entry.getKey());
                }
            }
        }
        return list;
    }

    @Override
    public Boolean modifyCarDetail(CarDetailModifyVo modifyDto) {
        return carDetailService.modifyCarDetail(Convert.toCarDetailModifyDto(modifyDto));
    }

    @Override
    public CarDetailVo getCarDetail(Integer carId) throws Exception {
        CarDetailVo carDetailVo = Convert.toCarDetailVo(carBizService.getCarDetail(carId));
        if (null != carDetailVo) {
            Map<Integer, VehicleNameBizDto> vehicleMap = vehicleBizService.getCarByModelNameList(Arrays.asList(carDetailVo.getVehicleId()));
            if (vehicleMap != null && (null != vehicleMap.get(carDetailVo.getVehicleId()))) {
                VehicleNameBizDto vehicleNameBizDto = vehicleMap.get(carDetailVo.getVehicleId());
                carDetailVo.setVehicleName(vehicleNameBizDto.getModelName());
                carDetailVo.setVehicleMake(vehicleNameBizDto.getSubBrandName());
                carDetailVo.setVehicleModel(vehicleNameBizDto.getSeriesName());
            }
            VehicleColorDto vehicleColorDto = vehicleColorService.getVehicleColorByvehicleColorId(carDetailVo.getVehicleColorId());
            if (vehicleColorDto != null) {
                carDetailVo.setVehicleColorName(vehicleColorDto.getName());
            }
            VehicleDto vehicleDto = vehicleService.getVehicleByVehicleId(carDetailVo.getVehicleId());
            if (null != vehicleDto && null != vehicleDto.getPowerType()) {
                carDetailVo.setPowerTypeStr(PowerTypeEnum.getName(vehicleDto.getPowerType()));
            }
            OwnershipDto ownershipDto = ownershipService.getOwnershipById(carDetailVo.getOwnershipId());
            if (null != ownershipDto) {
                carDetailVo.setOwnershipName(ownershipDto.getName());
            }
            ResponseResult<Map<String, IovMileageDto>> iovMap = iovCarService.getMileageByVins(Arrays.asList(carDetailVo.getVin()));
            if ((null != iovMap) && (ResponseCodeEnum.SUCCESS.getCode().equals(iovMap.getCode()))) {
                IovMileageDto iovMileageDto = iovMap.getData().get(carDetailVo.getVin());
                if (null != iovMileageDto) {
                    carDetailVo.setAccessType("TBox");
                    carDetailVo.setAccessCode(iovMileageDto.getDeviceId());
                    carDetailVo.setDashboardMileage(iovMileageDto.getMeterOdo() + "");
                    carDetailVo.setGpsMileage(iovMileageDto.getGpsOdo() + "");
                    carDetailVo.setDrivingName(iovMileageDto.getOdo() + "");
                }
            }
        }
        return carDetailVo;
    }

    @Override
    public Boolean uploadVehicleFile(Sheet sheet, UserEntity currentLoginUser) throws Exception {

        List<String> titleArray = Arrays.asList("*车架号", "*发动机/电机号", "*车型", "*生产年份", "*颜色", "*产权方", "合格证序号", "*车辆类型", "*失败原因");
        int successNumber = 0;
        int failNumber = 0;
        //创建两个List集合，一个保存属性文件中的字段值，一个保存Excel文件中每一行的单元格的值
        List<List<String>> errorList = new ArrayList<>();
        //遍历Excel文件
        //获取行数，第一行是标题
        int totalRows = sheet.getPhysicalNumberOfRows();
        if (totalRows < 2) {
            EmailUtil.sendMail(emailAccount, emailPassword, "车辆信息导入反馈", "【车辆信息】Excel文件为空", currentLoginUser.getAccount());
            return null;
        }
        Row row = null;
        int totalCells = 0;
        for (int i = 0; i < totalRows; i++) {
            List<String> valuesList = new ArrayList<>();
            //遍历单元格
            row = sheet.getRow(i);
            //获取每一行的单元格数
            totalCells = row.getPhysicalNumberOfCells();
            //循环设置每个单元格的数据类型为String类型
            for (int j = 0; j < titleArray.size() - 1; j++) {
                if (row.getCell(j) != null) {
                    row.getCell(j).setCellType(Cell.CELL_TYPE_STRING);
                }
            }
            //获取每个单元格的数据，保存到集合中
            StringBuffer errorReason = new StringBuffer();
            Boolean errorFlag = false;
            for (int t = 0; t < titleArray.size() - 1; t++) {
                if (null != row.getCell(t)) {
                    String cellInfo = row.getCell(t).getStringCellValue();
                    if (StringUtils.isEmpty(cellInfo)) {
                        errorFlag = true;
                    }
                    valuesList.add(cellInfo);
                } else {
                    valuesList.add(t, "");
                    errorFlag = true;
                }
            }
            //excel 列名不能操作
            if (i == 0) {
                if (errorFlag || valuesList.size() != 8) {
                    EmailUtil.sendMail(emailAccount, emailPassword, "车辆信息导入反馈", "【车辆信息】文件格式错误", "yixuelin@molichuxing.com");
                    return null;
                }
                continue;
            } else {
                if (errorFlag || valuesList.size() != 8) {
                    errorReason.append("数据不全");
                } else {
                    if (valuesList.get(0).length() != 17) {
                        errorReason.append("车架号格式不正确；");
                    }
                    CarDto carDto = carService.getCarByVin(valuesList.get(0));
                    if (null != carDto) {
                        errorReason.append("车架号已存在；");
                    }
                    CarDetailDto carDetailDto = carDetailService.getCarDetailByEngineCode(valuesList.get(1));
                    if (null != carDetailDto) {
                        errorReason.append("发动机/电机号已存在；");
                    }
                    VehicleNameBizDto vehicleNameBizDto = vehicleBizService.getCarByModelName(valuesList.get(2));
                    VehicleColorDto vehicleColorDto = null;
                    if (null == vehicleNameBizDto) {
                        errorReason.append("车型不存在；");
                    } else {
                        vehicleColorDto = vehicleColorService.getVehicleColorByVehicle(vehicleNameBizDto.getModelId(), valuesList.get(4));
                        if (null == vehicleColorDto) {
                            errorReason.append("颜色不存在；");
                        }
                    }
                    OwnershipDto ownershipDto = ownershipService.getOwnershipByName(valuesList.get(5));
                    if (null == ownershipDto) {
                        errorReason.append("产权方不存在；");
                    }
                    if (null == CarsTypeEnum.getEnum(valuesList.get(7))) {
                        errorReason.append("车辆类型不存在；");
                    }
                    if (StringUtils.isEmpty(errorReason)) {
                        VehicleCreateBizDto vehicleCreateBizDto = new VehicleCreateBizDto();
                        vehicleCreateBizDto.setVin(valuesList.get(0));
                        vehicleCreateBizDto.setEngineCode(valuesList.get(1));
                        vehicleCreateBizDto.setVehicleId(vehicleNameBizDto.getModelId());
                        vehicleCreateBizDto.setProductYear(Integer.parseInt(valuesList.get(3)));
                        if (null != vehicleColorDto) {
                            vehicleCreateBizDto.setColorId(vehicleColorDto.getId());
                        }
                        vehicleCreateBizDto.setOwnershipId(ownershipDto.getId());
                        vehicleCreateBizDto.setCertificateCode(valuesList.get(6));
                        vehicleCreateBizDto.setVehicleType(CarsTypeEnum.getEnum(valuesList.get(7)).getValue());
                        int result = carBizService.createBizCar(vehicleCreateBizDto);
                        if (result < 0) {
                            errorReason.append("增加车辆失败");
                        }
                        StockCarCreateDto stockCarCreateDto = new StockCarCreateDto();
                        stockCarCreateDto.setCarId(result);
                        stockCarCreateDto.setVehicleId(vehicleNameBizDto.getModelId());
                        stockCarCreateDto.setStatus(StockStatusEnum.WAIT_STOCK.getValue());
                        stockCarCreateDto.setType(StockCarTypeEnum.PURCHASE.getValue());
                        stockCarCreateDto.setCarStatus(CarsOperateStatusEnum.FOR_RENT.getValue());
                        stockCarCreateDto.setOutStockType(StockCarStockTypeEnum.ENTREPOT_STORAGE.getValue());
                        stockCarCreateDto.setOutOperationTime(LocalDateTime.now());
                        stockCarCreateDto.setOutAccountId(currentLoginUser.getAccountId());
                        stockCarCreateDto.setOutAccountAccount(currentLoginUser.getRealName());
                        stockCarCreateDto.setInStockType(StockCarStockTypeEnum.ENTREPOT_STORAGE.getValue());
                        stockCarCreateDto.setStorageTime(LocalDateTime.now());
                        stockCarCreateDto.setPurchaseDate(LocalDate.now());
                        stockCarCreateDto.setAccountId(currentLoginUser.getAccountId());
                        stockCarCreateDto.setAccountAccount(currentLoginUser.getRealName());
                        Boolean insertStockCarResult = stockCarService.create(stockCarCreateDto);
                        if (!insertStockCarResult) {
                            errorReason.append("增加库存车辆失败");
                        }
                    }
                }
            }

            if (StringUtils.isNotEmpty(errorReason)) {
                if (valuesList.size() <= 8) {
                    for (int j = valuesList.size(); j < 8; j++) {
                        valuesList.add(j, "");
                    }
                } else {
                    valuesList = valuesList.subList(0, 8);
                }
                valuesList.add(errorReason.toString());
                errorList.add(valuesList);
                failNumber++;
            } else {
                successNumber++;
            }
        }
        if (null == errorList || errorList.size() == 0) {
            EmailUtil.sendMail(emailAccount, emailPassword, "车辆信息导入反馈", "【车辆信息】" + successNumber + "条导入成功", currentLoginUser.getAccount());
        } else {
            //生成EXCEL
            XSSFWorkbook xssBook = PoiExcelUtils.createXSSFWorkbook(titleArray, errorList);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            try {
                xssBook.write(os);
            } catch (IOException e) {
                e.printStackTrace();
            }
            EmailUtil.sendMail(emailAccount, emailPassword, "车辆信息导入反馈", "【车辆信息】" + successNumber + "条导入成功，" + failNumber + "条导入失败！可下载详情失败数据", currentLoginUser.getAccount(),
                    "车辆导入.xlsx", new ByteArrayInputStream(os.toByteArray()));
        }
        return null;
    }


    @Override
    public Boolean uploadVehiclePdfFile(MultipartFile purchaseInvoiceFile, MultipartFile factoryCertificateFile, MultipartFile conformityCertificateFile,
                                        UserEntity currentLoginUser, String zipFilePath) throws Exception {
        List<String> titleArray = Arrays.asList("*车架号", "*类型", "*失败原因");
        //创建两个List集合，一个保存属性文件中的字段值，一个保存Excel文件中每一行的单元格的值
        List<List<String>> errorList = new ArrayList<>();
        Integer successNumber = new Integer(0);
        // 查询文件存储配置
        UploadFileRequestDto uploadFileRequestDto = fileStorageBffService.getFileStorageConfig("purchaseinvoice");
        if (uploadFileRequestDto != null) {
            List<UploadFileResponseDto> filePathList = UploadUtil.uploadZipFileToAll(purchaseInvoiceFile, uploadFileRequestDto);
            successNumber = updatePdfPath(filePathList, 1, errorList, successNumber);
        }
        uploadFileRequestDto = fileStorageBffService.getFileStorageConfig("factorycert");
        if (uploadFileRequestDto != null) {
            List<UploadFileResponseDto> filePathList = UploadUtil.uploadZipFileToAll(factoryCertificateFile, uploadFileRequestDto);
            successNumber = updatePdfPath(filePathList, 2, errorList, successNumber);
        }
        uploadFileRequestDto = fileStorageBffService.getFileStorageConfig("uniformitycert");
        if (uploadFileRequestDto != null) {
            List<UploadFileResponseDto> filePathList = UploadUtil.uploadZipFileToAll(conformityCertificateFile, uploadFileRequestDto);
            successNumber = updatePdfPath(filePathList, 3, errorList, successNumber);
        }
        if ((null == errorList || errorList.size() == 0) && (successNumber == 0)) {
            EmailUtil.sendMail(emailAccount, emailPassword, "车辆PDF导入反馈", DateUtil.formatDateNow() + "【车辆PDF】zip文件为空", currentLoginUser.getAccount());
            return true;
        }
        if (null == errorList || errorList.size() == 0) {
            EmailUtil.sendMail(emailAccount, emailPassword, "车辆PDF导入反馈", DateUtil.formatDateNow() + "【车辆PDF】" + successNumber + "条导入成功", currentLoginUser.getAccount());
        } else {
            //生成EXCEL
            XSSFWorkbook xssBook = PoiExcelUtils.createXSSFWorkbook(titleArray, errorList);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            try {
                xssBook.write(os);
            } catch (IOException e) {
                e.printStackTrace();
            }
            EmailUtil.sendMail(emailAccount, emailPassword, "车辆PDF导入反馈", DateUtil.formatDateNow() + "【车辆PDF】" + successNumber + "条导入成功，" + errorList.size() + "条导入失败！可下载详情失败数据", currentLoginUser.getAccount(),
                    "车辆PDF.xlsx", new ByteArrayInputStream(os.toByteArray()));
        }
        return true;
    }

    private Integer updatePdfPath(List<UploadFileResponseDto> filePathList, int type, List<List<String>> errorList, Integer successNumber) {
        if (null != filePathList && filePathList.size() > 0) {
            for (UploadFileResponseDto uploadFileResponseDto : filePathList) {
                List<String> errorStr = new ArrayList<>();
                if (StringUtils.isEmpty(uploadFileResponseDto.getFileName())) {
                    //记录原因
                    continue;
                }
                if (uploadFileResponseDto.getFileName().toLowerCase().indexOf(".pdf") == -1 || uploadFileResponseDto.getFileName().indexOf("+") == -1) {
                    errorStr.add(uploadFileResponseDto.getFileName());
                    if (type == 1) {
                        errorStr.add("购车发票");
                    }
                    if (type == 2) {
                        errorStr.add("出厂合格证");
                    }
                    if (type == 3) {
                        errorStr.add("一致性合格证");
                    }
                    errorStr.add("文件格式错误");
                    errorList.add(errorStr);
                    continue;
                }
                Integer startIndex = 0;
                if (uploadFileResponseDto.getFileName().contains("+")) {
                    startIndex = uploadFileResponseDto.getFileName().lastIndexOf("+") + 1;
                }
                String vin = uploadFileResponseDto.getFileName().substring(startIndex, uploadFileResponseDto.getFileName().lastIndexOf(".")).replace(" ", "");
                errorStr.add(vin);
                if (type == 1) {
                    errorStr.add("购车发票");
                }
                if (type == 2) {
                    errorStr.add("出厂合格证");
                }
                if (type == 3) {
                    errorStr.add("一致性合格证");
                }
                if (!".pdf".equalsIgnoreCase(uploadFileResponseDto.getFileName().substring(uploadFileResponseDto.getFileName().lastIndexOf(".")))) {
                    //记录原因
                    errorStr.add("格式有误");
                    errorList.add(errorStr);
                    continue;
                }
                CarDto carDto = carService.getCarByVin(vin);
                if (null == carDto) {
                    //记录原因
                    errorStr.add("无此车辆");
                    errorList.add(errorStr);
                    continue;
                }
                CarDetailDto carDetailDto = carDetailService.getCarDetailById(carDto.getId());
                if (null == carDetailDto) {
                    //记录原因
                    errorStr.add("无此车辆");
                    errorList.add(errorStr);
                    continue;
                }
                CarDetailModifyDto modifyDto = new CarDetailModifyDto();
                modifyDto.setId(carDto.getId());
                if (type == 1) {
                    if (StringUtils.isNotEmpty(carDetailDto.getPurchaseInvoiceImg())) {
                        //记录原因
                        errorStr.add("重复数据");
                        errorList.add(errorStr);
                        continue;
                    }
                    modifyDto.setPurchaseInvoice(uploadFileResponseDto.getFileUrl());
                    modifyDto.setPurchaseInvoiceImg(uploadFileResponseDto.getImgUrl());
                }
                if (type == 2) {
                    if (StringUtils.isNotEmpty(carDetailDto.getFactoryCertImg())) {
                        //记录原因
                        errorStr.add("重复数据");
                        errorList.add(errorStr);
                        continue;
                    }
                    modifyDto.setFactoryCert(uploadFileResponseDto.getFileUrl());
                    modifyDto.setFactoryCertImg(uploadFileResponseDto.getImgUrl());
                }
                if (type == 3) {
                    if (StringUtils.isNotEmpty(carDetailDto.getUniformityCertImg())) {
                        //记录原因
                        errorStr.add("重复数据");
                        errorList.add(errorStr);
                        continue;
                    }
                    modifyDto.setUniformityCert(uploadFileResponseDto.getFileUrl());
                    modifyDto.setUniformityCertImg(uploadFileResponseDto.getImgUrl());
                }
                Boolean result = carDetailService.modifyCarDetail(modifyDto);
                if (result) {
                    successNumber++;
                }
            }
        }
        return successNumber;
    }


    public static void main(String[] args) {
        String s = "购车发票+MOLICB3F9JW100233.PDF";
        System.out.println(s.toLowerCase().indexOf(".pdf"));
    }

    @Override
    public ResponseResult<List<String>> getTrajectoryTime(String vin) {
        return iovCarService.getTrajectoryTime(vin);
    }

    @Override
    public List<IovTrajectoryVo> getTrajectory(String vin, String startTime, String endTime) {
        ResponseResult<List<IovTrajectoryDto>> data = iovCarService.getTrajectory(vin, startTime, endTime);
        if ((null != data) && (ResponseCodeEnum.SUCCESS.getCode().equals(data.getCode()))) {
            return Convert.toIovTrajectoryVo(data.getData());
        }
        return null;
    }

    private Map<Integer, String> getCarName(List<CarBizDto> carDtoList) {
        Map<Integer, String> result = null;
        if (null != carDtoList && carDtoList.size() > 0) {
            Set<Integer> ids = new HashSet<>();
            for (CarBizDto carDto : carDtoList) {
                ids.add(carDto.getVehicleId());
            }
            List<Integer> vehicleIds = new ArrayList<>(ids);
            result = vehicleBizService.getVehicleFullName(vehicleIds);
        }
        return result;
    }

    private Map<Integer, String> getVehicleName(List<CarDto> carDtoList) {
        Map<Integer, String> result = null;
        if (null != carDtoList && carDtoList.size() > 0) {
            List<Integer> ids = new ArrayList<>();
            for (CarDto carDto : carDtoList) {
                ids.add(carDto.getVehicleId());
            }
            result = vehicleBizService.getVehicleFullName(ids);
        }
        return result;
    }

    private Map<Integer, VehicleColorDto> getCarColor(List<CarBizDto> carDtoList) {
        Map<Integer, VehicleColorDto> result = null;
        if (null != carDtoList && carDtoList.size() > 0) {
            Set<Integer> ids = new HashSet<>();
            for (CarBizDto carDto : carDtoList) {
                ids.add(carDto.getVehicleColorId());
            }
            List<Integer> vehicleColorIds = new ArrayList<>(ids);
            result = vehicleColorService.getVehicleColors(vehicleColorIds);
        }
        return result;
    }

    private Map<Integer, VehicleColorDto> getVehicleColor(List<CarDto> carDtoList) {
        Map<Integer, VehicleColorDto> result = null;
        if (null != carDtoList && carDtoList.size() > 0) {
            List<Integer> ids = new ArrayList<>();
            for (CarDto carDto : carDtoList) {
                ids.add(carDto.getVehicleColorId());
            }
            result = vehicleColorService.getVehicleColors(ids);
        }
        return result;
    }

    private void getVehicleStock(List<CarVo> carDtoList) {
        if (null != carDtoList && carDtoList.size() > 0) {
            List<Integer> ids = new ArrayList<>();
            List<Integer> vehicleIds = new ArrayList<>();
            for (CarVo carDto : carDtoList) {
                ids.add(carDto.getId());
                vehicleIds.add(carDto.getVehicleId());
                carDto.setOds(iovCarService.getCurrentMileage(carDto.getVin()));
            }
            Map<Integer, StockCarBizDto> stockCarBizMap = stockCarBizService.getStockBaseCars(ids);
            if (null != stockCarBizMap) {
                for (CarVo carDto : carDtoList) {
                    StockCarBizDto stockCarBizDto = stockCarBizMap.get(carDto.getId());
                    if (null != stockCarBizDto) {
                        if (stockCarBizDto.getStockType() == StockCarStockTypeEnum.ENTREPOT_STORAGE.getValue()) {
                            carDto.setStockName(stockCarBizDto.getStockName());
                        } else {
                            try {
                                DealerStoreInfoBizDto dealerStoreInfoBizDto = storeBizService.getDealerStoreInfo(stockCarBizDto.getStoreId());
                                carDto.setStockName(dealerStoreInfoBizDto.getDealerShortName() + "-" + dealerStoreInfoBizDto.getStoreShortName());
                            } catch (Exception e) {
                                logger.error("查询门店信息异常");
                            }
                        }
                    }
                }
            }
            Map<Integer, List<VehiclePictureDto>> pictureMap = vehiclePictureService.getVehiclePictureByVehicleIds(vehicleIds);
            if (null != pictureMap) {
                for (CarVo carDto : carDtoList) {
                    if (null != pictureMap.get(carDto.getVehicleId())) {
                        for (VehiclePictureDto vehiclePictureDto : pictureMap.get(carDto.getVehicleId())) {
                            if (vehiclePictureDto.getIsWhiteBg() && 1 == vehiclePictureDto.getPicDetailType()) {
                                carDto.setVehicleImg(vehiclePictureDto.getServerUrl());
                                break;
                            }

                        }
                    }
                }
            }

        }
    }

    private void getCarStock(List<CarVo> carDtoList) throws Exception {
        if (null == carDtoList || carDtoList.size() < 1) {
            return;
        }

        List<Integer> ids = carDtoList.stream().map(CarVo::getId).collect(Collectors.toList());
        List<IovMileageDto> mileageList = iovCarService.getMileage();
        Map<String, IovMileageDto> mileageMap = null;
        if (mileageList != null && mileageList.size() > 0) {
            mileageMap = mileageList.stream().collect(Collectors.toMap(IovMileageDto::getVin, a -> a, (k1, k2) -> k1));
        }
        Map<Integer, StockCarBizDto> stockCarBizMap = stockCarBizService.getStockBaseCars(ids);
        if (null == mileageMap && null == stockCarBizMap) {
            return;
        }
        List<Integer> storeIdList = null;
        if (stockCarBizMap != null && stockCarBizMap.size() > 0) {
            storeIdList = stockCarBizMap.values().stream().map(StockCarBizDto::getStoreId).collect(Collectors.toList());
        }
        Map<Integer, DealerStoreInfoBizDto> dealerStoreInfoMap = storeBizService.getDealerStoreInfoMap(storeIdList);
        for (CarVo carDto : carDtoList) {
            String vin = carDto.getVin();
            if (mileageMap != null && mileageMap.size() > 0) {
                IovMileageDto iovMileageDto = mileageMap.get(vin);
                if (iovMileageDto != null) {
                    carDto.setOdo(iovMileageDto.getOdo());
                }
            }

            if (stockCarBizMap != null && stockCarBizMap.size() > 0) {
                StockCarBizDto stockCarBizDto = stockCarBizMap.get(carDto.getId());
                if (null == stockCarBizDto) {
                    continue;
                }
                if (stockCarBizDto.getStockType() == StockCarStockTypeEnum.ENTREPOT_STORAGE.getValue()) {
                    carDto.setStockName(stockCarBizDto.getStockName());
                } else {
                    if (dealerStoreInfoMap != null && dealerStoreInfoMap.size() > 0) {
                        DealerStoreInfoBizDto dealerStoreInfoBizDto = dealerStoreInfoMap.get(stockCarBizDto.getStoreId());
                        if (dealerStoreInfoBizDto != null) {
                            carDto.setStockName(dealerStoreInfoBizDto.getDealerShortName() + "-" + dealerStoreInfoBizDto.getStoreShortName());
                        }
                    }
                }
            }
        }
    }

    /**
     * 车辆列表导出
     *
     * @param selectParams
     * @return
     */
    @Override
    public List<CarVo> getCarListDownload(Map<String, Object> selectParams) throws Exception {
        Integer stockType = ObjectCastUtil.castInteger(selectParams.get("stockType"));
        Integer stockId = ObjectCastUtil.castInteger(selectParams.get("stockId"));
        String carIdList = ObjectCastUtil.castString(selectParams.get("carIdList"));
        if (StringUtils.isNoneBlank(carIdList)) {
            selectParams.put("carIdList", Arrays.asList(carIdList.split(",")));
        }

        if ((null != stockType) && (StockCarStockTypeEnum.STORE.getValue() == stockType) && null != stockId) {
            StockStoreDto stockStoreDto = stockStoreService.getStockStoreByStoreId(stockId);
            if (stockStoreDto == null) {
                selectParams.put("stockId", 0);
            } else {
                selectParams.put("stockId", stockStoreDto.getStockId());
            }
        }
        List<String> strings = doHandler();
        List<CarBizDto> carDtoList = carBizService.getCarListDownload(selectParams);
        List<CarVo> carVoList = Convert.toCarVo(carDtoList, getCarName(carDtoList), getCarColor(carDtoList));
        getCarStock(carVoList);
        if(!CollectionUtils.isEmpty(carVoList)){
            for (CarVo carVo : carVoList) {
               if(CollectionUtils.isEmpty(strings)){
                   carVo.setVehicleLockStatus(2);
                   carVo.setVehicleLockStatusStr("否");
               }else{
                   if(strings.contains(carVo.getVin())){
                       carVo.setVehicleLockStatus(1);
                       carVo.setVehicleLockStatusStr("是");
                   }else{
                       carVo.setVehicleLockStatus(2);
                       carVo.setVehicleLockStatusStr("否");
                   }
               }
            }
        }
        return carVoList;
    }


    @Override
    public long getCarListDownloadCount(Map<String, Object> selectParams) throws Exception {
        Integer stockType = ObjectCastUtil.castInteger(selectParams.get("stockType"));
        Integer stockId = ObjectCastUtil.castInteger(selectParams.get("stockId"));
        String carIdList = ObjectCastUtil.castString(selectParams.get("carIdList"));
        if (StringUtils.isNoneBlank(carIdList)) {
            selectParams.put("carIdList", Arrays.asList(carIdList.split(",")));
        }

        if ((null != stockType) && (StockCarStockTypeEnum.STORE.getValue() == stockType) && null != stockId) {
            StockStoreDto stockStoreDto = stockStoreService.getStockStoreByStoreId(stockId);
            if (stockStoreDto == null) {
                selectParams.put("stockId", 0);
            } else {
                selectParams.put("stockId", stockStoreDto.getStockId());
            }
        }

        return carBizService.getCarListDownloadCount(selectParams);
    }

    @Async
    @Override
    public Boolean getCarListDownloadEmail(Map<String, Object> selectParams, UserEntity user) throws Exception {
        List<CarVo> carList = getCarListDownload(selectParams);
        String fileName = "车辆列表(" + DateUtil.formatDate(LocalDate.now()) + ").xlsx";
        // 生成excel
        SXSSFWorkbook sxssBook = PoiExcelUtil.getCarListDownload(carList);
        // 发送邮件
        EmailUtil.sendMail(emailAccount, emailPassword, "车辆列表数据", "车辆列表数据", user.getAccount(), fileName, sxssBook);
        return true;
    }

    @Override
    public List<CarDto> getByVinList(List<String> vinList) {
        return carService.getByVinList(vinList);
    }
    
    @Override
    public CarVo getCarByVin(String vin,Integer vehicleId) {
    	CarDto carDto = carService.getCarByVin(vin);
    	if(null == carDto) {
    		throw new BizException(101,"不存在该车辆信息");
    	}
    	if(!CarsOperateStatusEnum.FOR_RENT.getValue().equals(carDto.getStatus())) {
    		throw new BizException(101,"该车辆运营状态不是可运营状态");
    	}
    	if(!carDto.getVehicleId().equals(vehicleId)) {
    		throw new BizException(101,"车型不符");
    	}
    	StockCarDto stockCar = stockCarService.getStockCar(carDto.getId());
    	if(null == stockCar) {
    		throw new BizException(101,"不存在该车辆库存信息");
    	}
    	if(StockCarStatusEnum.WAIT_STOCK.getValue() == stockCar.getStatus()) {
    		throw new BizException(101,"该车辆不是已入库状态");
    	}
    	if(StockCarStockTypeEnum.ENTREPOT_STORAGE.getValue() != stockCar.getInStockType()) {
    		throw new BizException(101,"该车辆不是在中转库");
    	}
    	
    	boolean carIsLock = enterpriseCarService.getCarIsLock(carDto.getId());
		if(carIsLock) {
			throw new BizException("该车辆为锁定状态");
		}
		Boolean carIdCheck = orderDealerDeliveryService.carIdCheck(carDto.getId());
	    if(!carIdCheck){
	    	throw new BizException("该车辆为锁定状态");
	    }
	    CarVo vo =new CarVo();
	    BeanUtils.copyProperties(carDto, vo);
    	return vo;
    }

    @Override
    public Integer getCarOdoMileage(String vin) {
        CarDto carDto = carService.getCarByVin(vin);
        if(null == carDto) {
            throw new BizException(101,"不存在该车辆信息");
        }

       return iovCarService.getOdoMileage(vin);
    }

    
    @Override
    public CarVo getCarByVin(String vin) {
    	CarDto carDto = carService.getCarByVin(vin);
        if(null == carDto) {
            throw new BizException(101,"不存在该车辆信息");
        }
        if(carDto.getBusinessType().equals(CarsBusinessTypeEnum.EXCLUSIVE.getValue())
        		|| carDto.getBusinessType().equals(CarsBusinessTypeEnum.SUBSCRIBE.getValue())) {
        	CarVo vo =new CarVo();
     	    BeanUtils.copyProperties(carDto, vo);
     	    return vo;
        }
        throw new BizException(101,"该车辆当前业务类型不满足查询条件！");
    }


}
